#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BORRA_BUFFER    while(getchar()!= '\n');
#define MAX_MSG_LEN	200
#define MAX_BLOCK_LEN	10

int getLine (char * line, int linelen, FILE * stream);
int transRecurW (char * enc_msg, int key_len, char * des;);
int transRecur (int * orig, int * key, int key_len, int * used, int last, char * enc_msg, char * des, FILE * pfile);
void unset (int * used, int pos, int key_len);
int desTrans (int * key, int key_len, char * enc_msg, char * des, FILE * pfile);
int pairs (char * msg);
int pairsOk (char * msg, int key_len);

int
main (void)
{
	char msg_enc[MAX_MSG_LEN] = {0};
	int * key;
	char * des;
	int flag = 1, alf_len, msg_len;
	int block_len, i, j, k;
	int fact;
	
	
	printf("Ingrese el texto encriptado con metodo Transposicion: ");
	getLine (msg_enc, MAX_MSG_LEN, stdin);
	
	msg_len = strlen(msg_enc);
	
	des = (char *) calloc ( msg_len + 1, sizeof(char));
//	key = (int *) calloc ( MAX_BLOCK_LEN, sizeof(int));
	
	for (block_len = 2; block_len <= 5; block_len++)
	{		
		transRecurW (msg_enc, block_len, des);	
	}
	
	
	return 0;
}

int
getLine (char * line, int linelen, FILE * stream)
{
    int i=0, c;
    for (i=0;i<linelen;i++)
        line[i] = 0;
    i=0;
    while(i<linelen){
        c=fgetc(stream);
        if(c==EOF)
                return -1;

        if(c=='\n')
                return 1;

        line[i]=c;
        i++;
    }

    if (i >= linelen)
        {
            BORRA_BUFFER;
        return 0;
        }
    return 0;
}

int transRecurW (char * enc_msg, int key_len, char * des)
{
	int last = 0, i;
	int * orig;
	int * key;
	int * used;
	FILE * pfile;
	
	if ((pfile = fopen ("/home/nahu/Desktop/trans.txt", "w")) == NULL)
	{
		printf ("Error Fopen2\n");
		return 1;
	}
	
	orig = (int *) calloc (key_len, sizeof(int));
	key = (int *) calloc (key_len, sizeof(int));
	used = (int *) calloc (key_len, sizeof(int));
	
	for (i = 0; i < key_len; i++)
	{
		orig[i] = i;
		used[i] = -1;
	}
	transRecur (orig, key, key_len, used, last, enc_msg, des, pfile);
	fclose(pfile);
}

int transRecur (int * orig, int * key, int key_len, int * used, int last, char * enc_msg, char * des, FILE * pfile)
{
	int i;
	if (last == key_len - 1)
	{
		for (i = 0; i < key_len; i++)
		{
			if (used[i] == -1)
			{
				key[last] = orig[i];
				desTrans (key, key_len, enc_msg, des, pfile);
				return ;
			}
		}
	}
	
	for (i = 0; i < key_len; i++)
	{
		if (used[i] == -1)
		{
			key[last] = orig[i];
			used[i] = last;
			
			transRecur (orig, key, key_len, used, last +1, enc_msg, des, pfile);
			unset(used, last, key_len);
		}
	}
	return ;
	
	
}

void unset (int * used, int pos, int key_len)
{
	int i;
	
	for (i = 0; i < key_len; i++)
	{
		if (used[i] == pos)
		{
			used[i] = -1;
			return;
		}
	}
}

int desTrans (int * key, int key_len, char * enc_msg, char * des, FILE * pfile)
{
	int i, j;
	int msg_len;
	char * end = "\n\n";
	int end_len = strlen(end);
	
	
	msg_len = strlen(enc_msg);
	
	for (i = 0; i <= msg_len - key_len; i += key_len)
	{
		for(j = 0; j < key_len; j++)
			des[i + key[j]] = enc_msg[j + i];
	}
	
	des[msg_len] = 0;
	printf("KEY: ");
	for(i = 0; i < key_len; i++)
		printf("%d", key[i]);
	printf("\nMSG: %s\n", des);

	if (pairsOk(des, key_len))
		fprintf (pfile, "%s\n\n",des);
	
/*	if (pairs(des))
		fprintf (pfile, "%s\n\n",des);*/
	//fwrite ("\n\n", 1, end_len, pfile);
}

int pairs (char * msg)
{
	int msg_len;
	int coinc = 0;
	int mal = 0;
	int i,j;
	FILE * flow, *fhigh;
	char clow[2];
	char chigh[2];
	int hok = 1;
	int lok = 1;
	
	
	if ((fhigh = fopen ("/home/nahu/Desktop/Cripto/plow.txt", "r")) == NULL)
	{
		printf ("Error Fopen\n");
		return 1;
	}
	
	if ((flow = fopen ("/home/nahu/Desktop/Cripto/phigh.txt", "r")) == NULL)
	{
		printf ("Error Fopen2\n");
		return 1;
	}
	
	msg_len = strlen(msg);
	
	
		do
		{
			if (hok)
			{
				fscanf(fhigh, "%c%c,", chigh, chigh + 1);
				if (chigh[0] == '+' || chigh[1] == '+')
					hok = 0;
				else
				{
					for (i = 0; i < msg_len -1; i++)
					{
						if (strncmp (&(msg[i]), chigh, 2) == 0)
							coinc++;
					}
				}
			}
			if (lok)
			{
				fscanf(flow, "%c%c,", clow, clow + 1);
				if (clow[0] == '+' || clow[1] == '+')
					lok = 0;
				else
				{
					for (i = 0; i < msg_len -1; i++)
					{
						if (strncmp (&(msg[i]), clow, 2) == 0)
							mal++;
					}
				}
			}
		}
		while (hok && lok);
	
	
	printf("OK: %d\nMAL: %d\n", coinc, mal);
	fclose(flow);
	fclose(fhigh);
	
	if (coinc > (msg_len/5))
		return 1;
	return 0;
	
}

int pairsOk (char * msg, int key_len)
{
	char high[20][3] = {{"ue"},{"en"},{"de"},{"es"}, {"qu"}, {"er"}, {"os"}, {"la"}, {"as"}, {"an"}, {"ra"}, {"do"}, {"on"}, {"el"}, {"ar"}, {"se"}, {"re"}, {"co"}, {"te"}, {"or"}};
	int i, j, k;
	int ok = 0;
	int * key;
	char pair[2] = {0};
	
	key = (int *) calloc(key_len, sizeof(char));
	
	for (i = 0; i < key_len; i++)
	{
		for(j = 0; j < key_len; j++)
		{
			if (i != j)
			{
				pair[0] = msg[i];
				pair[1] = msg[j];
				for (k = 0; k < 20; k++)
				{
					if (strncmp(pair, high[j], 2) == 0)
						ok = 1;
				}
				
			}
			
		}
	}
	
	for (i = 0; i < key_len; i++)
		for (j = 0; j < 20; j++)
		{
			if (strncmp(msg + i, high[j], 2) == 0)
				ok = 1;
		}
	if (ok)
		for (i = 0; i < key_len; i++)
			for (j = 0; j < 20; j++)
			{
				if (strncmp(key_len + msg + i, high[j], 2) == 0)
					return 1;
			}
	return 0;
}